﻿using Abp.Extensions;
using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace Mt.Site.Core.AccessStatistics
{
    public static class SearchEngineHelper
    {
        public static SearchEngineInfo GetSearchEngines(string refererUrl)
        {
            var result = new SearchEngineInfo();

            if (Baidu(refererUrl, result)) { }
            else if (Google(refererUrl, result)) { }
            else if (Qh360(refererUrl, result)) { }
            else if (Bing(refererUrl, result)) { }
            else if (Sogou(refererUrl, result)) { }
            else if (ShenMa(refererUrl, result)) { }
            else if (Chinaso(refererUrl, result)) { }
            else if (Soso(refererUrl, result)) { }
            else if (YaHoo(refererUrl, result)) { }
            else if (Easou(refererUrl, result)) { }

            if(!result.Searchkey.IsNullOrEmpty())
            {
                result.Searchkey = Decode(result.Searchkey);
            }

            return result;
        }
        
        private static bool Baidu(string refererUrl, SearchEngineInfo result)
        {
            Regex regex = new Regex(@"^http(?:s)?://(.*?)(?:\.)?baidu\.com", RegexOptions.IgnoreCase);
            Match m = regex.Match(refererUrl);
            if(m.Success)
            {
                var groups = m.Groups;
                string type = groups.Count > 1 ? groups[1].Value : null;

                result.Searchkey = GetKEY(refererUrl, "?", "wd|word|key");
                result.IsSearchEngines = true;
                result.EngineType = "百度";

                switch (type)
                {
                    case "www":
                        result.EngineName = "百度网页搜索";
                        break;
                    case "m":
                        result.EngineName = "掌上百度";
                        break;
                    case "wap":
                        result.EngineName = "百度手机搜索";
                        break;
                    case "news":
                        result.EngineName = "百度新闻搜索";
                        break;
                    case "zhidao":
                        result.EngineName = "百度知道";
                        break;
                    case "wenku":
                        result.EngineName = "百度文库";
                        break;
                    default:
                        result.EngineName = "其他百度搜索";
                        break;
                }
                return true;
            }
            return false;
        }

        private static bool Google(string refererUrl, SearchEngineInfo result)
        {
            var refererUrl_Lower = refererUrl.ToLower();
            if (refererUrl_Lower.IndexOf(".google.") > -1)
            {
                //key:#|? q  tbm(类型)：nws新闻，vid视频，isch图片，pts专利，bks图书，blg博客，frm论坛，klg问答，app应用
                result.Searchkey = GetKEY(refererUrl, "?|#", "q");

                result.IsSearchEngines = true;
                result.EngineType = "谷歌";

                string type = GetKEY(refererUrl, "?|#", "tbm");
                switch(type)
                {
                    case "":
                        result.EngineName = "谷歌网页搜索";
                        break;
                    case "nws":
                        result.EngineName = "谷歌新闻搜索";
                        break;
                    case "isch":
                        result.EngineName = "谷歌图片搜索";
                        break;
                    case "vid":
                        result.EngineName = "谷歌视频搜索";
                        break;
                    case "fin":
                        result.EngineName = "谷歌财经搜索";
                        break;
                    default:
                        result.EngineName = "其他谷歌搜索";
                        break;
                }
                
                return true;
            }
            return false;
        }

        private static bool Qh360(string refererUrl, SearchEngineInfo result)
        {
            Regex regex = new Regex(@"^http(?:s)?://(.*?)(?:\.)?so\.com", RegexOptions.IgnoreCase);
            Match m = regex.Match(refererUrl);
            if (m.Success)
            {
                var groups = m.Groups;
                string type = groups.Count > 1 ? groups[1].Value : null;

                result.Searchkey = GetKEY(refererUrl, "?", "q|kw");
                result.IsSearchEngines = true;
                result.EngineType = "360";

                switch (type)
                {
                    case "www":
                        result.EngineName = "360网页搜索";
                        break;
                    case "m":
                        result.EngineName = "360手机搜索";
                        break;
                    case "m.news":
                        result.EngineName = "360手机资讯搜索";
                        break;
                    case "news":
                        result.EngineName = "360资讯搜索";
                        break;
                    case "m.image":
                        result.EngineName = "360手机图片搜索";
                        break;
                    case "m.video":
                        result.EngineName = "360手机视频搜索";
                        break;
                    case "wenda":
                        result.EngineName = "360问答";
                        break;
                    case "video":
                        result.EngineName = "360视频搜索";
                        break;
                    case "image":
                        result.EngineName = "360图片搜索";
                        break;
                    case "ly":
                        result.EngineName = "360良医搜索";
                        break;
                    case "music":
                        result.EngineName = "360音乐搜索";
                        break;
                    case "baike":
                        result.EngineName = "360百科";
                        break;
                    case "soft":
                        result.EngineName = "360软件搜索";
                        break;
                    default:
                        result.EngineName = "其他360搜索";
                        break;
                }
                return true;
            }
            return false;
        }

        private static bool Bing(string refererUrl, SearchEngineInfo result)
        {
            if (refererUrl.IndexOf(".bing.com") > -1)
            {
                result.Searchkey = GetKEY(refererUrl, "?", "q");
                result.IsSearchEngines = true;
                result.EngineType = "必应";

                if (refererUrl.IndexOf("/news/search?") > -1)
                    result.EngineName = "必应资讯搜索";
                else if (refererUrl.IndexOf("/dict/search?") > -1)
                    result.EngineName = "必应词典";
                else if (refererUrl.IndexOf("/videos/search?") > -1)
                    result.EngineName = "必应视频搜索";
                else if (refererUrl.IndexOf("/images/search?") > -1)
                    result.EngineName = "必应图片搜索";
                else if (refererUrl.IndexOf("/yingxiangli/search?") > -1)
                    result.EngineName = "必应影响力搜索";
                else
                    result.EngineName = "必应网页搜索";

                return true;
            }
            return false;
        }

        private static bool Sogou(string refererUrl, SearchEngineInfo result)
        {
            Regex regex = new Regex(@"^http(?:s)?://(.*?)(?:\.)?sogou\.com", RegexOptions.IgnoreCase);
            Match m = regex.Match(refererUrl);
            if (m.Success)
            {
                var groups = m.Groups;
                string type = groups.Count > 1 ? groups[1].Value : null;

                result.Searchkey = GetKEY(refererUrl, "?", "query|keyword");
                result.IsSearchEngines = true;
                result.EngineType = "搜狗";

                switch (type)
                {
                    case "www":
                        result.EngineName = "搜狗网页搜索";
                        break;
                    case "m":
                        result.EngineName = "搜狗手机搜索";
                        break;
                    case "news":
                        result.EngineName = "搜狗资讯搜索";
                        break;
                    case "pic":
                        result.EngineName = "搜狗图片搜索";
                        break;
                    case "v":
                        result.EngineName = "搜狗视频搜索";
                        break;
                    case "wap":
                        result.EngineName = "搜狗手机搜索";
                        break;
                    case "zhishi":
                        result.EngineName = "搜狗知识";
                        break;
                    default:
                        result.EngineName = "其他搜狗搜索";
                        break;
                }
                return true;
            }
            return false;
        }

        private static bool Soso(string refererUrl, SearchEngineInfo result)
        {
            Regex regex = new Regex(@"^http(?:s)?://(.*?)(?:\.)?soso\.com", RegexOptions.IgnoreCase);
            Match m = regex.Match(refererUrl);
            if (m.Success)
            {
                var groups = m.Groups;
                string type = groups.Count > 1 ? groups[1].Value : null;

                result.Searchkey = GetKEY(refererUrl, "?", "query");
                result.IsSearchEngines = true; ;
                result.EngineType = "搜搜";

                switch (type)
                {
                    case "www":
                        result.EngineName = "搜搜网页搜索";
                        break;
                    case "news":
                        result.EngineName = "搜搜新闻搜索";
                        break;
                    default:
                        result.EngineName = "搜搜";
                        break;
                }
                return true;
            }
            return false;
        }

        private static bool YaHoo(string refererUrl, SearchEngineInfo result)
        {
            if (refererUrl.IndexOf(".yahoo.") > 0)
            {
                result.Searchkey = GetKEY(refererUrl, "?", "q");
                result.IsSearchEngines = true; ;
                result.EngineType = "雅虎";
                result.EngineName = "雅虎搜索";

                return true;
            }
            return false;
        }

        private static bool Easou(string refererUrl, SearchEngineInfo result)
        {
            if (refererUrl.IndexOf(".easou.") > 0)
            {
                result.Searchkey = GetKEY(refererUrl, "?", "q");
                result.IsSearchEngines = true; ;
                result.EngineType = "宜搜";
                result.EngineName = "宜搜";

                return true;
            }
            return false;
        }

        private static bool Chinaso(string refererUrl, SearchEngineInfo result)
        {
            Regex regex = new Regex(@"^http(?:s)?://(.*?)(?:\.)?chinaso\.com", RegexOptions.IgnoreCase);
            Match m = regex.Match(refererUrl);
            if (m.Success)
            {
                var groups = m.Groups;
                string type = groups.Count > 1 ? groups[1].Value : null;

                result.Searchkey = GetKEY(refererUrl, "?", "q");
                result.IsSearchEngines = true;
                result.EngineType = "中国搜索";

                switch (type)
                {
                    case "www":
                        result.EngineName = "中国搜索";
                        break;
                    case "m":
                        result.EngineName = "手机国搜";
                        break;
                    case "news":
                        result.EngineName = "国搜新闻";
                        break;
                    case "image":
                        result.EngineName = "国搜图片";
                        break;
                    case "v":
                        result.EngineName = "国搜视频";
                        break;
                    case "m.v":
                        result.EngineName = "手机国搜视频";
                        break;
                    case "m.news":
                        result.EngineName = "手机国搜新闻";
                        break;
                    case "m.image":
                        result.EngineName = "手机国搜图片";
                        break;
                    default:
                        result.EngineName = "中国搜索";
                        break;
                }
                return true;
            }
            return false;
        }

        private static bool ShenMa(string refererUrl, SearchEngineInfo result)
        {
            if (refererUrl.IndexOf(".sm.cn") > -1)
            {
                result.Searchkey = GetKEY(refererUrl, "?", "q");
                result.IsSearchEngines = true;
                result.EngineType = "神马搜索";
                result.EngineName = "神马网页搜索";

                return true;
            }
            return false;
        }

        private static string GetKEY(string FromUrl, string a, string b)
        {
            string[] paraName = b.Split('|');
            string[] splitChars = a.Split('|');
            for (int k = 0; k < splitChars.Length; k++)
            {
                string[] paras = FromUrl.Split(new string[] { splitChars[k] }, StringSplitOptions.RemoveEmptyEntries);
                if (paras.Length > 1)
                {
                    string[] para = paras[1].Split('&');
                    for (int i = 0; i < para.Length; i++)
                    {
                        string[] pair = para[i].Split('=');
                        for (int j = 0; j < paraName.Length; j++)
                        {
                            if (pair[0] == paraName[j] && pair.Length > 1)
                                return pair[1];
                        }
                    }
                }
            }
            return "";
        }

        public static string Decode(string strUrl)
        {
            //将URL转为小写
            string lowerUrl = strUrl.ToLower();
            //判断URL中是否包含%，如果不包含%就不需要解码
            if (lowerUrl.IndexOf('%') != -1)
            {
                ////判断URL中是否包含%E，如果不包含直接用GB2312解码
                //if (lowerUrl.IndexOf("%e") != -1)
                //{
                //    //以UTF-8对URL进行解码
                //    string stringUrl = WebUtility.UrlDecode(strUrl, Encoding.UTF8);
                //    //判断解码后的字符串是否为UTF-8编码
                //    if (CheckIsUTF8(stringUrl))
                //        return stringUrl;
                //    else
                //        return WebUtility.UrlDecode(strUrl, Encoding.GetEncoding("GB2312"));
                //}
                return WebUtility.UrlDecode(strUrl);
            }
            return strUrl;
        }
        private static bool CheckIsUTF8(string url)
        {
            //转成UTF-8字节数组
            byte[] bs = Encoding.UTF8.GetBytes(url);
            for (int i = 0; i < bs.Length; i++)
            {
                //查找字节239 191 189(乱码)，如果找到退出循环，标记为GB2312
                if (i < bs.Length - 2)
                {
                    if (bs[i] == 239 && bs[i + 1] == 191 && bs[i + 2] == 189)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    }

    public class SearchEngineInfo
    {
        public bool IsSearchEngines { get; set; }

        public string EngineName { get; set; }

        //主要搜索引擎referer中搜索关键字已经都不提供了
        public string Searchkey { get; set; }

        public string EngineType { get; set; }
    }
}
